package org.myOrg.spetrum.spectrumStruct;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.myOrg.spetrum.combination.Tuple;
import org.myOrg.spetrum.combination.TupleCase;
import org.myOrg.spetrum.combination.TupleCaseImplement;
import org.myOrg.spetrum.testObject.TestCase;
import org.myOrg.spetrum.testObject.TestSuite;
import org.myOrg.spetrum.testObject.TestSuiteImplement;
import org.myOrg.spetrum.testRun.TestRun;

public class SpetrumAnalyseBase implements Spectrum {
	protected SpetrumSetup setUp;
	protected List<Tuple> bugs;
	protected TestSuite generateTestCases;
	protected TestRun run;
	protected int id;

	public SpetrumAnalyseBase(TestRun run,int[] param, TestSuite wrongTestCases,
			TestSuite rightTestCases) {
		setInput(param , wrongTestCases, rightTestCases);
		this.run = run;
		generateTestCases = new TestSuiteImplement();
		bugs = new ArrayList<Tuple>();
		id = SpectrumFactory.BASE;
	}

	public SpetrumAnalyseBase() {
		generateTestCases = new TestSuiteImplement();
		bugs = new ArrayList<Tuple>();
		id = SpectrumFactory.BASE;
	}

	@Override
	public void setInput(int[] param ,TestSuite wrongTestCases, TestSuite rightTestCases) {
		// TODO Auto-generated method stub
		setUp = new SpetrumSetup(param,wrongTestCases, rightTestCases);
		init();
	}

	@Override
	public void setRun(TestRun run) {
		this.run = run;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.myOrg.spetrum.spectrumStruct.Spectrum#init()
	 */
	@Override
	public void init() {
		Iterator<TupleAnalyseStruct> itr = getTupleManager().iterator();
		while (itr.hasNext()) {
			itr.next().setSuspicion(1);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.myOrg.spetrum.spectrumStruct.Spectrum#isOver()
	 */
	@Override
	public boolean isOver() {
		return setUp.isAllTested();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.myOrg.spetrum.spectrumStruct.Spectrum#run()
	 */
	@Override
	public void run() {
		while (!isOver()) {
			Tuple tuple = this.getTestTuple();
			boolean judgeResult = this.generateTestCaseToJudge(tuple);
			if (judgeResult) {
				doRight(tuple);

			} else {
				doWrong(tuple);
			}
		}

		bugs = this.getTupleManager().getBugTuple();
	}

	public void doWrong(Tuple tuple) {
		// TODO Auto-generated method stub
		TupleAnalyseStruct struct = getTupleManager()
				.getTupleAnalyseStructByTuple(tuple);
		setsTructWrong(struct);

		Iterator<TupleAnalyseStruct> fathers = struct.getAllFathers().iterator();
		while (fathers.hasNext()) {
			setsTructWrong(fathers.next());
		}
	}

	public void setsTructWrong(TupleAnalyseStruct struct) {
		struct.setTested(true);
		struct.setPassOrFail(false);
	}

	public void setsTructRight(TupleAnalyseStruct struct) {
		struct.setPassOrFail(true);
		struct.setTested(true);
		struct.setSuspicion(0);
	}

	public void doRight(Tuple tuple) {

		TupleAnalyseStruct current = getTupleManager()
				.getTupleAnalyseStructByTuple(tuple);
		setsTructRight(current);

		Iterator<TupleAnalyseStruct> childs = current.getAllChilds().iterator();
		while (childs.hasNext()) {
			setsTructRight(childs.next());
		}
	}

	public Tuple getTestTuple() {
		// TODO Auto-generated method stub
		Iterator<TupleAnalyseStruct> itr = getTupleManager().iterator();
		double max = 0;
		TupleAnalyseStruct result = null;
		while (itr.hasNext()) {
			TupleAnalyseStruct temp = itr.next();
			if (!temp.isTested() && temp.getTestValuable() > max) {
				max = temp.getTestValuable();
				result = temp;
			}
		}
		return result.getTuple();
	}

	public boolean generateTestCaseToJudge(Tuple tuple) {
		TupleCase tupleCase = new TupleCaseImplement();
		TestCase testCase = tupleCase.getCaseFromTuple(tuple,
				setUp.generateOneRightTestCase());

		this.generateTestCases.addTest(testCase);

		run.runTestCase(testCase);
		return testCase.testDescription() == TestCase.PASSED;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.myOrg.spetrum.spectrumStruct.Spectrum#clear()
	 */
	@Override
	public void clear() {
		this.bugs.clear();
		this.generateTestCases.clear();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.myOrg.spetrum.spectrumStruct.Spectrum#getGenerateTestCases()
	 */
	@Override
	public TestSuite getGenerateTestCases() {
		return generateTestCases;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.myOrg.spetrum.spectrumStruct.Spectrum#getBugs()
	 */
	@Override
	public List<Tuple> getBugs() {
		return bugs;
	}

	public TupleStructSets getTupleManager() {
		return setUp.getTupleManager();
	}

	@Override
	public int getParamLength() {
		// TODO Auto-generated method stub
		return setUp.getParam().length;
	}

	@Override
	public int getSpectrumID() {
		// TODO Auto-generated method stub
		return id;
	}

}
